/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO.MySQL;

import Biblioteca.Library;
import ClassesListas.Imagens;
import ClassesUnicas.Imagem;
import DAO.DAOImagemApresentadaSubFase;
import java.io.IOException;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.ArrayList;

/**
 * DAOImagemMySQL

 Versao 1.0

 Data Criação 10/02/2014
 *
 * @author Igor
 */
public class DAOImagemApresentadaSubFaseMySQL extends DAOConexaoMySQL implements DAOImagemApresentadaSubFase {

    @Override
    public Imagem buscaImagemApresentadaSubFase(long idRosto, long idExpressao, long intensidade) throws Exception {
        ResultSet result = null;
        Imagem imagem = null;

        result = this.select.executeQuery("select * from ( "
                + "\n select a.*, '1' as SEQUENCIA_IMAGEM,"
                + " b.DESCRICAO as EXPRESSAO,"
                + "concat('./banco_de_dados/imagens/',b.DESCRICAO,'/',lpad(a.INTENSIDADE,3,'0'),a.ID_ROSTO,'.jpg') as DIRETORIO\n"
                + " from imagem a join expressao b on b.ID_EXPRESSAO = a.ID_EXPRESSAO "
                + "\n where a.INTENSIDADE = " + intensidade
                + "\n and a.ID_ROSTO = " + idRosto
                + "\n and a.ID_EXPRESSAO = " + idExpressao
                + "\n ) as myalias1 order by rand()");

        while (result.next()) {
            imagem = new Imagem();

            imagem.setIdRosto(result.getLong("ID_ROSTO"));
            imagem.setIdExpressao(result.getLong("ID_EXPRESSAO"));
            imagem.setIntensidade(result.getLong("INTENSIDADE"));
            imagem.setDiretorio(constroiDiretorioImagem(result.getString("DIRETORIO")));

        }

        return imagem;
    }

    @Override
    public ArrayList<Imagens> buscaVariasImagensApresentadasSubFase(long intensidade, int repetirImagens, long idFase) throws Exception {
        String strSQL = "";

        if(Library.getConfigTREF("TREF_Sistema").equals("DESENVOLVIMENTO")){
            strSQL = "select * from( \n";
        } 

        strSQL = strSQL+ "select @rownum:=@rownum+1 SEQUENCIA_IMAGEM, myalias1.* from (\n";
        for (; repetirImagens > 0; repetirImagens--) {
            strSQL = strSQL + "select\n"
                    + "distinct a.*,\n"
                    //+ "b.DESCRICAO as EXPRESSAO,\n"
                    + "concat('./banco_de_dados/imagens/',b.DESCRICAO,'/',lpad(a.INTENSIDADE,3,'0'),a.ID_ROSTO,'.jpg') as DIRETORIO\n"
                    + "from imagem a join expressao b on b.ID_EXPRESSAO = a.ID_EXPRESSAO\n"
                    + "join imagem_aparece_fase c on a.ID_ROSTO = c.ID_ROSTO and a.ID_EXPRESSAO = c.ID_EXPRESSAO and a.INTENSIDADE = c.INTENSIDADE\n"
                    + "where a.INTENSIDADE = " + intensidade + " or a.INTENSIDADE = 0 and c.ID_FASE = "+ idFase +"\n";
            if (repetirImagens > 1) {
                strSQL = strSQL + "union all\n";
            }
        }
        strSQL = strSQL + " order by rand()) as myalias1, (SELECT @rownum:=0) r";
        if(Library.getConfigTREF("TREF_Sistema").equals("DESENVOLVIMENTO")){
            strSQL = strSQL + ") myalias2 where SEQUENCIA_IMAGEM <= 1";
        } 

        ResultSet result = null;
        result = this.select.executeQuery(strSQL);

        ArrayList<Imagens> imagensLista = new ArrayList<>();
        //Pega informacoes da primeira linha
        
        while (result.next()) {
            Imagem imagem = new Imagem();

            imagem.setIdImagemSusFase(result.getLong("SEQUENCIA_IMAGEM"));
            imagem.setIdRosto(result.getLong("ID_ROSTO"));
            imagem.setIdExpressao(result.getLong("ID_EXPRESSAO"));
            imagem.setIntensidade(result.getLong("INTENSIDADE"));
            imagem.setDiretorio(constroiDiretorioImagem(result.getString("DIRETORIO")));

            Imagens imagens = new Imagens();
            imagens.getImagens().add(imagem);

            imagensLista.add(imagens);
        }
        return imagensLista;
        
    }

    public ArrayList<Imagens> buscaVariasImagensApresentadasDinamicamenteSubFase(int repetirImagens, long idFase) throws Exception {
        String strSQL = "";
        long idRosto = -1;
        long idExpressao = -1;

        if(Library.getConfigTREF("TREF_Sistema").equals("DESENVOLVIMENTO")){
            strSQL = "select * from( \n";
        }
        strSQL = strSQL+"select @rownum:=@rownum+1 SEQUENCIA_IMAGEM, myalias1.* from (\n";
        for (; repetirImagens > 0; repetirImagens--) {
            strSQL = strSQL + "select\n"
                    + "bb.*,\n"
                    + "concat('./banco_de_dados/imagens/',aa.DESCRICAO,'/',lpad(bb.INTENSIDADE,3,'0'),bb.ID_ROSTO,'.jpg') as DIRETORIO\n"
                    + "from(\n"
                    + "select distinct hh.ID_ROSTO, hh.ID_EXPRESSAO, cc.DESCRICAO\n"
                    + "from imagem hh\n"
                    + "join expressao cc on cc.ID_EXPRESSAO = hh.ID_EXPRESSAO\n"
                    + "where hh.ID_EXPRESSAO <> 0\n"
                    + "and (select count(*) from imagem zz where zz.ID_ROSTO = hh.ID_ROSTO and zz.ID_EXPRESSAO = hh.ID_EXPRESSAO and zz.INTENSIDADE in (25,50,75,100)) = 4\n"
                    + "order by rand()\n"
                    + ") aa\n"
                    + "join imagem bb on bb.ID_ROSTO = aa.ID_ROSTO and bb.ID_EXPRESSAO = aa.ID_EXPRESSAO\n"
                    + "join imagem_aparece_fase cc on bb.ID_ROSTO = cc.ID_ROSTO and bb.ID_EXPRESSAO = cc.ID_EXPRESSAO and bb.INTENSIDADE = cc.INTENSIDADE\n"
                    + "where cc.ID_FASE = "+idFase+"\n";
            if (repetirImagens > 1) {
                strSQL = strSQL + "union all\n";
            }
        }
        strSQL = strSQL + " ) as myalias1, (SELECT @rownum:=0) r\n";
        if(Library.getConfigTREF("TREF_Sistema").equals("DESENVOLVIMENTO")){
            strSQL = strSQL + ") myalias2 where SEQUENCIA_IMAGEM <= 20";
        }

        ResultSet result = null;
        result = this.select.executeQuery(strSQL);

        ArrayList<Imagens> imagensLista = new ArrayList<>();
        //Pega informacoes da primeira linha
        Imagens imagens = new Imagens();
        while (result.next()) {
            Imagem imagem = new Imagem();

            imagem.setIdImagemSusFase(result.getLong("SEQUENCIA_IMAGEM"));
            imagem.setIdRosto(result.getLong("ID_ROSTO"));
            imagem.setIdExpressao(result.getLong("ID_EXPRESSAO"));
            imagem.setIntensidade(result.getLong("INTENSIDADE"));
            imagem.setDiretorio(constroiDiretorioImagem(result.getString("DIRETORIO")));

            //Se for o primeiro registro
            if (result.getRow() == 1) {
                idRosto = result.getLong("ID_ROSTO");
                idExpressao = result.getLong("ID_EXPRESSAO");
            } else //Se tiver mudado o Rosto/Expressao
            if ((idRosto != result.getLong("ID_ROSTO")) || (idExpressao != result.getLong("ID_EXPRESSAO"))) {
                imagensLista.add(imagens);
                imagens = new Imagens();
                idRosto = result.getLong("ID_ROSTO");
                idExpressao = result.getLong("ID_EXPRESSAO");
            }

            //Insere somente depois de realizar os teste, pois se mudou o Rosto/Expressao, deve-se inserir na ListaGeral para depois na ListaSecundaria
            imagens.getImagens().add(imagem);

            //Cria imagem neutra
            if (imagens.getImagens().get(0).getIntensidade() != 0) {
                Imagem imagemNeutra = new Imagem();
                imagemNeutra.setIdImagemSusFase(0);
                imagemNeutra.setIdRosto(idRosto);
                imagemNeutra.setIdExpressao(idExpressao);
                imagemNeutra.setIntensidade(0);
                imagemNeutra.setDiretorio(constroiDiretorioImagem("./banco_de_dados/imagens/neutro/000" + idRosto + ".jpg"));
                imagens.getImagens().add(0, imagemNeutra);
            }
        }

        //Insere no final, pois o ultimo elemento nao eh inserido
        imagensLista.add(imagens);

        return imagensLista;
    }

    @Override
    public void gravaImagemApresentadaSubFase(long idIstanciaSubFase, Imagem imagem, long tempoParaAvalia) throws Exception {
        int acertouErrou = 0; //Errou a resposta

        if (imagem.getIdExpressaoResposta() != null) {
            if (imagem.getIdExpressao() == imagem.getIdExpressaoResposta()) {
                acertouErrou = 1; //Acertou a resposta
            }
        }

        CallableStatement cs;
        cs = this.con.getCon().prepareCall("{? = call GRAVA_IMAGEM_SUB_FASE(?,?,?,?,?,?,?,?)}");
        
        cs.registerOutParameter(1, Types.DECIMAL);
        cs.setLong(2, imagem.getIdImagemSusFase());
        cs.setLong(3, idIstanciaSubFase);
        cs.setLong(4, imagem.getIdRosto());
        cs.setLong(5, imagem.getIdExpressao());
        cs.setInt(6, (int) imagem.getIntensidade());
        cs.setLong(7, tempoParaAvalia);
        cs.setInt(8, acertouErrou); //Errou
        if (imagem.getIdExpressaoResposta() != null) {
            cs.setLong(9, imagem.getIdExpressaoResposta());
        } else {
            cs.setNull(9, java.sql.Types.NUMERIC);
        }

        cs.execute();
        //Retorno e gambiarra para funcionar o codigo
        //gambiarra
        long vReturn = cs.getLong(1);

        this.con.getStm().executeBatch();

    }

    @Override
    public Path constroiDiretorioImagem(String dir) throws IOException {
        Path path = Paths.get(dir);
        Path realPath = path.toRealPath(LinkOption.NOFOLLOW_LINKS);
        return realPath;
    }

}
